#lang racket


(require "../base/base.rkt")

(require "domain.rkt"
         "surface.rkt")

(provide (struct-out sinwave-surface)
         sinwave-object
         sinwave-tangent
         sinwave-normal
         sinwave-binormal
         make-sinwave-surface)


(define-struct (sinwave-surface surface)
  (ax ay az)
  #:constructor-name new-sinwave-surface)

(define (sinwave-object ax ay az)
  (λ (u v)
    (let ((x (* ax u))
          (y (* ay v)))
      (xyz
       x
       y
       (* az (sin (sqrt (+ (^2 x) (^2 y)))))))))

(define (sinwave-tangent object-proc)
  (λ (u v)
    (surface-tangent object-proc)))

(define (sinwave-normal object-proc)
  (λ (u v)
    (surface-normal object-proc)))

(define (sinwave-binormal)
  surface-binormal)

(define (make-sinwave-surface ax ay az)
  (new-sinwave-surface
   (sinwave-object ax ay az)
   (sinwave-tangent (sinwave-object ax ay az))
   (sinwave-normal (sinwave-object ax ay az))
   (sinwave-binormal)
   (make-domain 'closed (- 2pi) 'closed 2pi)
   (make-domain 'closed (- 2pi) 'closed 2pi)
   ax
   ay
   az))